package com.imooc.coupon.advice;

import com.imooc.coupon.annotation.IgnoreResponseAdvice;
import com.imooc.coupon.support.vo.CommonResponse;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Objects;

/**
 *对响应体数据进行增强
 * Created By TINY
 * Create Time 2020/2/9 - 12:58
 **/
@RestControllerAdvice // 组合了@ControllerAdvice & @ResponseBody注解
public class ResponseDataAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 是否需要对响应进行处理，true 则执行beforeBodyWrite
     * @param methodParameter 对应控制器中的目标方法信息
     * @param aClass 消息转换器
     * @return 是否需要处理
     */
    @Override
    @SuppressWarnings("all")
    public boolean supports(MethodParameter methodParameter,
                            Class<? extends HttpMessageConverter<?>> aClass) {

        // 如果当前方法对应的类上标注了 @IgnoreResponseAdvice 注解，则不需要处理
        if (methodParameter.getDeclaringClass().isAnnotationPresent(
                IgnoreResponseAdvice.class
        )) {
            return false;
        }

        // 如果当前方法标注了 @IgnoreResponseAdvice 注解，则不需要处理
        return !Objects.requireNonNull(methodParameter.getMethod()).isAnnotationPresent(
                IgnoreResponseAdvice.class
        );
    }

    /**
     * 对响应数据进行处理
     * @param o 响应数据对象
     * @param methodParameter    controller中对应的方法信息包装
     * @param mediaType          响应数据的媒体类型
     * @param aClass             消息转换器
     * @param serverHttpRequest  请求
     * @param serverHttpResponse 响应
     * @return
     */
    @Override
    @SuppressWarnings("all")
    public Object beforeBodyWrite(Object o,
                                  MethodParameter methodParameter,
                                  MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass,
                                  ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {

        CommonResponse<Object> response = new CommonResponse<>(
                0, ""
        );

        if (null == o) {
            // 如果响应数据为 null ，直接返回统一响应
            return response;
        } else if (o instanceof CommonResponse) {
            // 如果响应数据就是 CommonResponse 类型，不需要处理
            response = (CommonResponse<Object>) o;
        } else { response.setData(o); }        // 需要处理

        return response;
    }
}
